// Copyright 2010 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package both;

import com.google.api.adwords.lib.AdWordsService;
import com.google.api.adwords.lib.AdWordsServiceLogger;
import com.google.api.adwords.lib.AdWordsUser;
import com.google.api.adwords.v13.KeywordTraffic;
import com.google.api.adwords.v13.KeywordTrafficRequest;
import com.google.api.adwords.v13.KeywordType;
import com.google.api.adwords.v13.TrafficEstimatorInterface;
import com.google.api.adwords.v200909.cm.AdGroupCriterion;
import com.google.api.adwords.v200909.cm.AdGroupCriterionIdFilter;
import com.google.api.adwords.v200909.cm.AdGroupCriterionPage;
import com.google.api.adwords.v200909.cm.AdGroupCriterionSelector;
import com.google.api.adwords.v200909.cm.AdGroupCriterionServiceInterface;
import com.google.api.adwords.v200909.cm.Keyword;
import com.google.api.adwords.v200909.cm.KeywordMatchType;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * This demo shows how v13 and v200909 can be used within the same class. The
 * v13 service TrafficEstimator retrieves traffic estimations from the
 * keywords selected from the v200909 service AdGroupCriterionService.
 */
public class TrafficEstimatorDemo {
  public static void main(String args[]) throws Exception {
    // Log SOAP XML request and response.
    AdWordsServiceLogger.log();

    // Get AdWordsUser from "~/adwords.properties".
    AdWordsUser user = new AdWordsUser();

    // Get v13 traffic estimator service.
    TrafficEstimatorInterface trafficEstimatorService =
        user.getService(AdWordsService.V13.TRAFFIC_ESTIMATOR_SERVICE);

    // Get v200909 AdGroupCriterionService.
    AdGroupCriterionServiceInterface adGroupCriterionService =
        user.getService(AdWordsService.V200909.ADGROUP_CRITERION_SERVICE);

    Long adGroupId = Long.parseLong("INSERT_AD_GROUP_ID_HERE");

    // Create selector to get all criteria under ad group.
    AdGroupCriterionSelector selector = new AdGroupCriterionSelector();
    selector.setIdFilters(new AdGroupCriterionIdFilter[] {
        new AdGroupCriterionIdFilter(null, adGroupId, null)});

    Map<Keyword, KeywordTraffic> keywordTrafficMap = new HashMap<Keyword, KeywordTraffic>();

    // Get all keywords for ad group.
    AdGroupCriterionPage page = adGroupCriterionService.get(selector);

    if (page.getEntries() != null) {
      for (AdGroupCriterion adGroupCriterion : page.getEntries()) {
        if (adGroupCriterion.getCriterion() instanceof Keyword) {
          keywordTrafficMap.put((Keyword) adGroupCriterion.getCriterion(), null);
        }
      }

      List<KeywordTrafficRequest> keywordTrafficRequests = new ArrayList<KeywordTrafficRequest>();
      List<Keyword> keywords = new ArrayList<Keyword>(keywordTrafficMap.keySet());

      // Make a traffic estimation request for each keyword.
      for (Keyword keyword : keywords) {
        keywordTrafficRequests.add(new KeywordTrafficRequest(keyword.getText(),
            convertMatchType(keyword.getMatchType()), null));
      }

      // Get the traffic estimation of all the keywords.
      KeywordTraffic[] keywordTraffic =
          trafficEstimatorService.checkKeywordTraffic(
              keywordTrafficRequests.toArray(new KeywordTrafficRequest[] {}));

      // Put result back into map where order is preserved.
      for (int i = 0; i < keywords.size(); i++) {
        keywordTrafficMap.put(keywords.get(i), keywordTraffic[i]);
      }

      // Display results.
      System.out.println("Keywords are estimated to have traffic:");
      print(keywordTrafficMap);
    }
  }

  /**
   * Converts from a v13 traffic estimator match type to a v2009 match type
   * @param matchType the v13 traffic estimator match type
   * @return the v2009 match type
   */
  private static KeywordType convertMatchType(KeywordMatchType matchType) {
    if (matchType == KeywordMatchType.BROAD) {
      return KeywordType.Broad;
    } else if (matchType == KeywordMatchType.EXACT) {
      return KeywordType.Exact;
    } else if (matchType == KeywordMatchType.PHRASE) {
      return KeywordType.Phrase;
    } else {
      return null;
    }
  }

  /**
   * Pretty prints {@code map} using the {@code toString()} method.
   */
  private static void print(Map<Keyword, KeywordTraffic> map) {
    System.out.println("{");
    for (Entry<Keyword, KeywordTraffic> entry : map.entrySet()) {
      System.out.println("\t" + entry.getKey().getText() + ":"
          + entry.getKey().getMatchType() + " => " + entry.getValue());
    }
    System.out.println("}");
  }
}
